﻿using System.Collections.Generic;
using Roslyn.Compilers.CSharp;

namespace InterfaceWeaver.CustomTool
{
    public interface IAspectHandler
    {
        /// <summary>
        /// Handles the on namespace.
        /// </summary>
        /// <param name="dispatcher">The context.</param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <param name="namespaceDeclarationSyntax">The namespace declaration syntax.</param>
        /// <returns>
        /// True if the aspect is handled, false otherwise
        /// </returns>
        bool HandleOnNamespace(
            AspectDispatcher dispatcher, 
            AttributeSyntax attributeSyntax,
            NamespaceDeclarationSyntax namespaceDeclarationSyntax);

        /// <summary>
        /// Determines whether the aspect is known and could be handled by aspect handler.
        /// </summary>
        /// <param name="dispatcher">The context.</param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <returns></returns>
        bool HandleOnInterfacePreview(
           AspectDispatcher dispatcher,
           AttributeSyntax attributeSyntax);

        /// <summary>
        /// Regarding all the handler answering preview step, this step determines whether there are some aspect handler that should be removed from next live cycle.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <param name="indirectAspectHandler"> </param>
        /// <param name="indirectAttributeSyntax"> </param>
        /// <returns></returns>
        bool IsIndirectAspectsCompliantOnInterface(
            AspectDispatcher context, 
            AttributeSyntax attributeSyntax, 
            IAspectHandler indirectAspectHandler, 
            AttributeSyntax indirectAttributeSyntax);

        /// <summary>
        /// Gets the handling priority on interface.
        /// </summary>
        /// <param name="dispatcher">The dispatcher.</param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <param name="interfaceDeclarationSyntax">The interface declaration syntax.</param>
        /// <returns></returns>
        AspectHandlingPriority GetHandlingPriorityOnInterface(
            AspectDispatcher dispatcher,
            AttributeSyntax attributeSyntax,
            InterfaceDeclarationSyntax interfaceDeclarationSyntax);

        /// <summary>
        /// Handles the on interface.
        /// </summary>
        /// <param name="dispatcher">The context.</param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <param name="interfaceDeclarationSyntax">The interface declaration syntax.</param>
        /// <returns>
        /// True if the aspect is handled, false otherwise
        /// </returns>
        void HandleOnInterface(AspectDispatcher dispatcher, AttributeSyntax attributeSyntax, InterfaceDeclarationSyntax interfaceDeclarationSyntax);

        /// <summary>
        /// Determines whether the aspect is known and could be handled by aspect handler.
        /// </summary>
        /// <param name="context"> </param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <returns></returns>
        bool HandleOnPropertyPreview(
            AspectDispatcher context, 
            AttributeSyntax attributeSyntax);

        /// <summary>
        /// Regarding all the handler answering preview step, this step determines whether there are some aspect handler that should be removed from next live cycle.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <param name="indirectAspectHandler"> </param>
        /// <param name="indirectAttributeSyntax"> </param>
        /// <returns></returns>
        bool IsIndirectAspectsCompliantOnProperty(
            AspectDispatcher context, 
            AttributeSyntax attributeSyntax, 
            IAspectHandler indirectAspectHandler, 
            AttributeSyntax indirectAttributeSyntax);

        /// <summary>
        /// Gets the handling priority on property.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <param name="propertyDeclarationSyntax">The property declaration syntax.</param>
        /// <returns></returns>
        AspectHandlingPriority GetHandlingPriorityOnProperty(
            AspectDispatcher context, 
            AttributeSyntax attributeSyntax, 
            PropertyDeclarationSyntax propertyDeclarationSyntax);

        /// <summary>
        /// Handles the on member.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <param name="propertyDeclarationSyntax"> </param>
        /// <param name="handlerStreams"> </param>
        /// <returns>
        /// True if the aspect is handled, false otherwise
        /// </returns>
        void HandleOnProperty(AspectDispatcher context, AttributeSyntax attributeSyntax, PropertyDeclarationSyntax propertyDeclarationSyntax, IDictionary<PropertyDeclarationSyntax, AspectTuple[]> handlerStreams);
    }
}
